//
// Created by EmFi on 2023/5/12.
//

#include <iostream>
#include "Point.h"

double Point::getX() const {
    return x;
}

void Point::setX(double x) {
    Point::x = x;
}

double Point::getY() const {
    return y;
}

void Point::setY(double y) {
    Point::y = y;
}

double Point::getZ() const {
    return z;
}

void Point::setZ(double z) {
    Point::z = z;
}

double Point::getW() const {
    return w;
}

void Point::setW(double w) {
    Point::w = w;
}

int Point::push(double num) {
    if (num == NULL) {
        this->empty_flag[push_index] = true;
    }
    switch (this->push_index) {
        case 0:
            this->setX(num);
            break;
        case 1:
            this->setY(num);
            break;
        case 2:
            this->setZ(num);
            break;
        case 3:
            this->setW(num);
            break;
    }
    return this->push_index++;
}

std::ostream &operator<<(std::ostream &os, const Point &point) {
    os << "x: " << point.x << "\ty: " << point.y << "\tz: " << point.z << "\tw: " << point.w;
    return os;
}

void Point::fill() {
    int c = 0;
    double total = 0;
    if (!empty_flag[0]) {
        total += x;
        c++;
    }
    if (!empty_flag[1]) {
        total += y;
        c++;
    }
    if (!empty_flag[2]) {
        total += z;
        c++;
    }
    if (!empty_flag[3]) {
        total += w;
        c++;
    }
    double avg = total / c;
    if (empty_flag[0]) {
        this->setX(avg);
        empty_flag[0] = false;
    }
    if (empty_flag[1]) {
        this->setY(avg);
        empty_flag[1] = false;
    }
    if (empty_flag[2]) {
        this->setZ(avg);
        empty_flag[2] = false;
    }
    if (empty_flag[3]) {
        this->setW(avg);
        empty_flag[3] = false;
    }
}

bool Point::operator==(const Point &rhs) const {
    return empty_flag == rhs.empty_flag &&
           push_index == rhs.push_index &&
           x == rhs.x &&
           y == rhs.y &&
           z == rhs.z &&
           w == rhs.w;
}

bool Point::operator!=(const Point &rhs) const {
    return !(rhs == *this);
}

bool Point::check() {
    for (bool i : this->empty_flag) {
        if (i) {
            return false;
        }
    }
    return true;
}
